package site.xuqing.nobean.obj;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author xuqing
 * @Description 通用数据对象类
 * @createTime 2022年01月19日 14:37:30
 */
public class NonObject implements INonObject {
    private Map<String, Object> fieldMap;
    private Map<String, INonObject> objectMap;
    private Map<String, List<INonObject>> listMap;
    
    public NonObject() {
        fieldMap = new HashMap<>();
        objectMap = new HashMap<>();
        listMap = new HashMap<>();
    }
    
    @Override
    public <T> T getValue(String key) {
        return fieldMap.get(key) == null ? null : (T) fieldMap.get(key);
    }
    
    @Override
    public <T> T findableValue(String key) {
        List<T> data = new ArrayList<>();
        findableValue(key, data);
        return data.get(0);
    }
    
    /**
     * 递归查找
     *
     * @param key      key
     * @param findData 要查找的数据
     * @param <T>      查找的数据类型
     */
    private <T> void findableValue(String key, List<T> findData) {
        if (fieldMap.get(key) != null) {
            findData.add((T) fieldMap.get(key));
        } else {
            for (INonObject value : objectMap.values()) {
                ((NonObject) value).findableValue(key, findData);
            }
        }
    }
    
    @Override
    public Map<String, Object> getFieldMap() {
        return fieldMap;
    }
    
    @Override
    public <T> INonObject setValue(String key, T value) {
        if (fieldMap.containsKey(key)) {
            fieldMap.replace(key, value);
        } else {
            fieldMap.put(key, value);
        }
        return this;
    }
    
    @Override
    public INonObject getObject(String key) {
        return objectMap.get(key);
    }
    
    @Override
    public INonObject findableObject(String key) {
        List<INonObject> data = new ArrayList<>();
        findableObject(key, data);
        return data.get(0);
    }
    
    /**
     * 递归查找object
     *
     * @param key      key
     * @param findData List<INonObject>
     */
    private void findableObject(String key, List<INonObject> findData) {
        if (objectMap.get(key) != null) {
            findData.add(objectMap.get(key));
        } else {
            for (INonObject value : objectMap.values()) {
                ((NonObject) value).findableObject(key, findData);
            }
        }
    }
    
    @Override
    public Map<String, INonObject> getObjectMap() {
        return objectMap;
    }
    
    @Override
    public INonObject setObject(String key, INonObject object) {
        if (objectMap.containsKey(key)) {
            objectMap.replace(key, object);
        } else {
            objectMap.put(key, object);
        }
        return this;
    }
    
    @Override
    public List<INonObject> getList(String key) {
        return listMap.get(key);
    }
    
    @Override
    public Map<String, List<INonObject>> getListMap() {
        return listMap;
    }
    
    @Override
    public INonObject setList(String key, List<INonObject> list) {
        if (listMap.containsKey(key)) {
            listMap.replace(key, list);
        } else {
            listMap.put(key, list);
        }
        return this;
    }
    
    @Override
    public void clear() {
        fieldMap.clear();
        objectMap.clear();
        listMap.clear();
        fieldMap = null;
        objectMap = null;
        listMap = null;
    }
}
